<template>
    <div class="speech-item">
        <div class="header">
            <div class="left-info">
                <div class="avatar">
                    <image class="default" v-if="!data.createByAvatar" src="@/static/mine_default_avatar.png"/>
                    <image class="real" v-else :src="data.createByAvatar"/>
                </div>
                <div class="user">
                    <text class="name">{{data.createByNickName}}</text>
                    <text class="time" v-if="mode != 'preview'">{{data.createTime}}</text>
                </div>
            </div>
            <div v-if="!['preview', 'detail'].includes(mode) && data.isTop" class="top-btn">置顶</div>
        </div>
        <div 
            class="part"
            :class="{last: index == (data.contentList && data.contentList.length - 1)}" 
            v-for="(part, index) in data.contentList || []" 
            :key="index"
        >
            <text class="part-label">{{part.title}}</text>
            <div class="text-content">
                <rich-text :nodes="formatContent(part.content)"></rich-text>
            </div>
            <div class="topic" v-if="part.topics">
                <text class="title">相关话题：</text>
                <div class="topic-list">
                    <div 
                        class="topic-item" 
                        v-for="(topic, index) in clip(part)" 
                        :key="index"
                        @click.stop="toExam(topic)"
                    >
                        <text class="name">{{topic.topicType}}</text>
                        <div class="to" v-if="mode != 'preview' && topic.id">
                            去练习
                            <image class="" src="@/static/icon-arrow.png"></image>
                        </div>
                    </div>
                    <div class="topic-item more" v-if="part.hasMore" @click.stop="($event) => toggleMore(part, index)">
                        <text class="name">{{part.more ? '收起' : '展开'}}</text>
                        <image 
                            :class="[part.more ? 'more-show' : '']" 
                            src="@/static/icon-arrow2.png" 
                            alt=""
                        />
                    </div>
                </div>
            </div>
        </div>
        <div class="place-info" v-if="data.examiner">
            <text class="part-label">考点信息</text>
            <div class="tags">
                <text class="tag" v-for="(item, index) in data.examiner" :key="index">{{item}}</text>
            </div>
            <div class="content" v-if="data.examRoom">
                <rich-text :nodes="formatContent(data.examRoom)"></rich-text>
            </div>
        </div>
        <div class="gps-time" :class="{bottom30: ['preview', 'detail'].includes(mode)}">
            <text class="name">{{listData.centerName}}</text>
            <text class="time">考试日期：{{listData.speakExamDate}}</text>
        </div>
        <div 
            class="handler bottom30" 
            v-if="!['preview', 'detail'].includes(mode)" 
            @click.stop
        >
            <view class="icon-item">
                <button open-type="share" class="share-btn" :data-id="data.id" data-type="1" @click.stop="addShare">
                    <image class="" src="@/static/icon-share.png"></image>
                </button>
                {{formatNum(data.shares)}}
            </view>
            <view class="icon-item" @click="$emit('to-detail', data, 'comment')">
                <image class="" src="@/static/icon-comment.png"></image>
                {{formatNum(data.comments)}}
            </view>
            <view class="icon-item" @click="handleStar">
                <image v-if="!data.isLike" class="" src="@/static/icon-star.png"></image>
                <image v-else class="" src="@/static/icon-star-active.png"></image>
                {{formatNum(data.likes)}}
            </view>
        </div>
    </div>
</template>

<script>
    import {apiLike, apiAddShares} from '@/api/memory'
    export default {
        props: {
            mode: { // 预览模式
                default: 'all',
                type: String
            },
            listData: { // 回忆数据
                default: () => ({}),
                type: Object
            }
        },
        data() {
            return {
                query: null,
                data: this.listData || {},
                scene: ''
            }
        },
        watch: {
            listData: {
                deep: true,
                immediate: true,
                async handler(val){
                    if(Object.keys(val).length){
                        await this.$nextTick()
                        this.formatTopic()
                    }
                }
            }
        },
        created() {
            this.scene = wx.getLaunchOptionsSync().scene
        },
        methods: {
            // 增加分享数
            addShare(){
                apiAddShares({ 
                    id: this.data.id
                }).then(res => {
                    if(res.code == 200){
                        this.data.shares+=1
                    }
                }).catch(err => {
                    console.log(err, 'err')
                })
            },
            // 点赞
            handleStar(){
                // 朋友圈打开
                if(this.scene == 1154) return this.$tip.toast('请前往小程序使用完整服务')
                apiLike({ 
                    type: 1,
                    targetId: this.data.id,
                    isLike: this.data.isLike ? 0 : 1
                }).then(res => {
                    if(res.code == 200){
                        this.data.isLike = !this.data.isLike
                        if(this.data.isLike){
                            this.$tip.toast('点赞成功')
                            this.data.likes+=1
                        }else {
                            this.data.likes-=1
                            // this.$tip.toast('取消点赞成功')
                        }
                    }
                }).catch(err => {
                    console.log(err, 'err')
                })
            },
            formatNum(num){
                return num > 999 ? '999+' : num
            },
            // 去练习
            toExam(topic){
                if(this.mode == 'preview' || !topic.id) return
                const {timeStr, topicType, topicSeries, partType} = topic
                uni.navigateTo({
                    url: '/pages/exam/spokenExam?timeStr=' + timeStr + '&topicType=' +encodeURIComponent(topicType)+ '&topicSeries=' +topicSeries+ '&partType=' + partType
                })
            },
            // 切换展开收起
            toggleMore(part, index){
                part.more = !part.more
                this.$set(this.data.contentList, index, part)
            },

            // 动态选择展开收起需要的数据
            clip(data){
                if(data.more){
                    return data.topics
                }else {
                    return data.clip
                }
            },

            // 话题做展开收起
            async formatTopic(){
                const query = uni.createSelectorQuery().in(this)
                const lineDom = await this.getIns('.gps-time', query.select) // 话题列表的宽度
                let charWidth = 12 // 单字符的宽度
                const moreBtnWidth = charWidth * 3 + 20 * 2 // 更多按钮的宽度
                const margin = 18 // 话题间的右边距
                let isPreviewWidth = this.mode == 'preview' ? 0 : charWidth * 4 + 10 // 预览时有去练习的文字，文字的宽度
                let content = this.listData.contentList
                let contentList = content.map(item => {
                    let itemWidth = [] // 每个话题的宽度计算后存放的数组
                    let allWidth = 0 // 所有话题项的总宽度
                    item.topics && item.topics.length > 1 && item.topics.forEach(topic => {
                        const textWidth = charWidth * Number(topic.topicType.length) + 15 * 2 + isPreviewWidth + margin // 话题的宽度，文本的宽+间距
                        itemWidth = [...itemWidth, textWidth]
                        allWidth+= textWidth
                    })
                    // console.log(itemWidth, 'itemWidth')
                    let count = 0 // 一行可以显示几个话题
                    let computeWidth = 0 // 计算的一行可以显示的话题的总宽度
                    if(itemWidth){
                        itemWidth.forEach((text, index) => {
                            if(computeWidth + moreBtnWidth + text < lineDom.width){
                                computeWidth += text
                                count++
                            }
                            // if(index != itemWidth.length - 1 && computeWidth + text < lineDom.width){
                            //     computeWidth += text
                            //     count++
                            // }
                            // if(index == itemWidth.length - 1 && computeWidth + text < lineDom.width){
                            //     count = itemWidth.length
                            // }
                            
                        })
                    }
                    // console.log(itemWidth,computeWidth, count, 'width, count')
                    let hasMore = false
                    if(item.topics && item.topics.length > 1 && allWidth > lineDom.width){ // 一行显示不下则显示更多按钮，能显示或者只有一个话题或者没话题，都不显示更多
                        hasMore = true
                    }

                    let clip = [...item.topics || []] // 初始要显示的话题
                    if(count && hasMore){
                        clip = clip.slice(0, count)
                    }
                    // console.log({
                    //     ...item,
                    //     hasMore,
                    //     more: false,
                    //     count,
                    //     clip
                    // })
                    return {
                        ...item,
                        hasMore,
                        more: false,
                        count,
                        clip
                    }
                })
                this.data = {
                    ...this.listData,
                    contentList
                }
            },
            getIns(select, query){
                const dom = query(select)
                return new Promise((resolve, reject) => {
                    dom.boundingClientRect(res => {
                        resolve(res)
                    }).exec()
                })
            },

            // 换行处理
            formatContent(str){
                const arr = str.split('\n')
                return arr.map((item, index) => {
                    let node = `<span class='rich'>${item}</span>`
                    if(index != arr.length - 1){
                        node+= '<br/>'
                    }
                    return node
                }).join('')
            }
        },
    }
</script>

<style lang="scss" rel="stylesheet/scss" scoped>
@function toRem($rpx){  //$rpx为需要转换的字号
    @return #{$rpx * 100 / 750 / 4}rem; 
}
.speech-item{
    width: 100%;
    background-color: #fff;
    border-radius: toRem(10);
    padding: toRem(23) toRem(20) 0;
    box-sizing: border-box;
    // margin-top: toRem(17);
    margin-bottom: toRem(20);
    .header{
        display: flex;
        align-items: flex-start;
        margin-bottom: toRem(20);
        justify-content: space-between;
        width: 100%;
        .left-info{
            display: flex;
            align-items: center;
            flex: 1;
            min-width: 0;
            .avatar{
                width: toRem(70);
                height: toRem(70);
                border-radius: 50%;
                margin-right: toRem(20);
                background-color: #EAEEF6;
                position: relative;
                .default{
                    width: toRem(29);
                    height: toRem(32);
                    position: absolute;
                    left:50%;
                    top:50%;
                    transform: translate(-50%,-50%);
                }
                .real{
                    width: 100%;
                    height: 100%;
                    border-radius: 50%;
                }
            }
            .user{
                display: inline-flex;
                flex-direction: column;
                align-items: flex-start;
                font-size: toRem(24);
                font-weight: 400;
                color: #333;
                flex: 1;
                min-width: 0;
                .name{
                    overflow: hidden; /* 确保超出容器的文本被裁剪 */
                    white-space: nowrap; /* 确保文本在一行内显示 */
                    text-overflow: ellipsis;
                    max-width: 90%;
                }
                .time{
                    color: #999;
                }
            }
        }
        .top-btn{
            font-size: toRem(24);
            font-weight: 400;
            color: #F57878;
            padding: toRem(8) toRem(12);
            box-sizing: border-box;
            border-radius: toRem(8);
            border: toRem(2) solid #F8CBCB;
            background-color: #FFF4F4;
        }
    }
    
    .part{
        padding-bottom: toRem(30);
        border-bottom: toRem(1) solid #F5F5F5;
        margin-bottom: toRem(39);
        
        .text-content{
            font-size: toRem(28);
            color: #333;
            line-height: toRem(40);
        }
        .rich{
            line-height: toRem(40);
            font-size: toRem(28);
        }
        .topic{
            .title{
                color: #999;
                font-size: toRem(24);
                margin-top: toRem(30);
                display: inline-block;
            }
            .topic-list{
                width: 100%;
                .topic-item{
                    display: inline-flex;
                    align-items: center;
                    justify-content: space-between;
                    padding: toRem(10) toRem(19);
                    box-sizing: border-box;
                    border-radius: toRem(10) toRem(30) toRem(30) 0;
                    border: toRem(2) solid #F8CBCB;
                    background-color: #FFF4F4;
                    margin: toRem(20) toRem(20) 0 0;
                    width: auto;
                    .name{
                        font-size: toRem(24);
                        color: #F57878;
                    }
                    .to{
                        display: inline-flex;
                        align-items: center;
                        font-size: toRem(19);
                        color: #999;
                        margin-left: toRem(40);
                        image{
                            width: toRem(9);
                            height: toRem(17);
                            margin-left: toRem(10);
                        }
                    }
                }
                .more{
                    margin-right: 0;
                    image{
                        width: toRem(9);
                        height: toRem(17);
                        margin-left: toRem(10);
                    }
                    .more-show{
                        transform: rotate(180deg);
                    }
                }
            }
        }
        
    }
    .part-label{
        border-radius: toRem(10) toRem(19) toRem(19) 0;
        background-color: #F6F6F6;
        color: #999;
        font-size: toRem(24);
        padding: toRem(10) toRem(15);
        box-sizing: border-box;
        margin-bottom: toRem(16);
        display: inline-block;
    }
    .last{
        margin-bottom: 0;
        border: none;
    }
    .place-info{
        .part-label{
            margin-bottom: toRem(19);
        }
        .tags{
            width: 100%;
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            justify-content: flex-start;
            .tag{
                display: inline-flex;
                align-items: center;
                font-size: toRem(24);
                color: #333;
                margin-bottom: toRem(20);
                position: relative;
                margin-right: toRem(60);
                &::before{
                    content: '';
                    width: toRem(6);
                    height: toRem(6);
                    border-radius: 50%;
                    background-color: #000;
                    margin-right: toRem(10);
                }
            }
        }
        .content{
            width: 100%;
            background-color: #F6F6F6;
            border-radius: toRem(10);
            color: #333;
            font-size: toRem(28);
            line-height: toRem(32);
            padding: toRem(20);
            box-sizing: border-box;
        }
        .rich{
            line-height: toRem(40);
            font-size: toRem(28);
        }
    }
    .gps-time{
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-top: toRem(28);
        font-size: toRem(24);
        color: #333;
        .name{
            flex: 1;
            text-overflow: ellipsis;
            overflow: hidden;
            white-space: nowrap;
            margin-right: toRem(30);
        }
        .time{
            color: #999;
            font-size: toRem(20);
        }
    }
    .handler{
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: toRem(30) toRem(70) 0;
        font-size: toRem(20);
        color: #999;
        .icon-item{
            display: inline-flex;
            align-items: center;

        }
        image{
            width: toRem(24);
            height: toRem(24);
            margin-right: toRem(9);
        }
    }
    .bottom30{
        padding-bottom: toRem(30);
    }
}
.share-btn{
    border: none;
    padding: 0;
    margin: 0;
    line-height: 1;
    background-color: rgba(0,0,0,0);
    &::after{
        border: none;
    }
}

 
</style>

